package com.binarycube.webserver.datasource;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.List;

import org.apache.log4j.Logger;

import com.binarycube.webserver.config.DatasourceConfig;
import com.binarycube.webserver.datasource.Parameter.Type;

public class JDBCDataSource extends AbstractDataSource implements IDataSource{
	static Logger log = Logger.getLogger(JDBCDataSource.class.getName());
	
	public enum QueryType {
		UPDATE, QUERY;
	}
	
	String url;
	String user ;
	String pword;
	String query;
	
	QueryType type = QueryType.QUERY;
	
	public List<Record> doQuery() {
		validateParams();
		
		Connection con = null;
        ResultSet rs = null;

      
        try {
            con = DriverManager.getConnection(url, user, pword);
           
            NamedParameterStatement st = new NamedParameterStatement(con, query);
            for (Parameter param : _params.values()) {
            	if (param.getType() == Type.STRING) st.setString(param.getName(), param.getStringValue());
            	if (param.getType() == Type.LONG) st.setLong(param.getName(), param.getLongValue());
            	if (param.getType() == Type.INTEGER) st.setInt(param.getName(), param.getIntegerValue());
            	if (param.getType() == Type.TIMESTAMP) st.setTimestamp(param.getName(), param.getTimestampValue());
            }
           
            if (type == QueryType.QUERY) {
            	rs = st.executeQuery();
            	 ResultSetMetaData meta = rs.getMetaData();
                 
                 int colCount = meta.getColumnCount();

                 while (rs.next()) {
                 	Record r = Record.MappedRecord();
                 	for (int i=1; i <= colCount; i++) {
                 		r.put(meta.getColumnName(i), rs.getObject(i));
                 	}
                 	_records.add(r);
                 	
                 }
                 
            } else {
            	st.executeUpdate();
            	
            }
                     
            
           

        } catch (SQLException ex) {
           log.error("Error performing JDBC datasource query: " + _config.getName(), ex);

        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (con != null) {
                    con.close();
                }

            } catch (SQLException ex) {
            	log.error("Error closing JDBC datasource connection: "+ _config.getName(), ex);
            }
        }
		return _records;
	}
	
	public void configure(DatasourceConfig config) {
		super.configure(config);
		url = _config.getProperty("url");
		user = _config.getProperty("user");
		pword = _config.getProperty("password");
		query = _config.getProperty("query");
		String tmp = _config.getProperty("type");
		if (tmp != null) type = QueryType.valueOf(tmp);
	}


	
}
